<script setup lang="tsx">
import { computed, PropType, reactive, ref } from 'vue'
import { Dialog } from '@/components/Dialog'
import { ElForm, ElMessage, FormInstance, FormRules } from 'element-plus'
import { useDesign } from '@/hooks/web/useDesign'
import { PageData, SelectOption, SelectTreeOption } from '@/api/common/types'
import { getDictionarySelectOptionList } from '@/utils/dictionary'
import { SystemMenu } from '@/api/system/menu/types'
import {
  checkMenuCodeApi,
  createSystemMenuApi,
  getUsableMenuListApi,
  updateSystemMenuApi
} from '@/api/system/menu'
import antIcons from '@/components/Icon/data/icons.ant-design'
import tIcons from '@/components/Icon/data/icons.tdesign'
import epIcons from '@/components/Icon/data/icons.ep'
import { Icon } from '@/components/Icon'
import { useIcon } from '@/hooks/web/useIcon'

const props = defineProps({
  modelValue: {
    type: Boolean
  },
  refreshList: {
    type: Function,
    required: true
  },
  menu: {
    type: Object as PropType<SystemMenu>
  },
  title: {
    type: String
  },
  create: {
    type: Boolean
  }
})
const validateMenuCode = (rule, value, callback) => {
  if (value === undefined || value === null || value === '') {
    callback(new Error('菜单编码不能为空'))
  } else {
    checkMenuCodeApi({
      menuCode: value,
      menuId: systemMenu.menuId
    })
      .then((res) => {
        if (res?.data) {
          callback(new Error(res?.data))
        } else {
          callback()
        }
      })
      .catch(() => {
        callback(new Error('请求异常，请联系管理员！'))
      })
  }
}
const rules = reactive<FormRules<SystemMenu>>({
  menuName: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
  parentId: [{ required: true, message: '菜单名称不能为空', trigger: 'change' }],
  component: [{ required: true, message: '组件路径不能为空', trigger: 'blur' }],
  menuPath: [{ required: true, message: '菜单路径不能为空', trigger: 'blur' }],
  menuCode: [{ required: true, trigger: 'blur', validator: validateMenuCode }],
  menuIcon: [{ required: true, message: '菜单名称不能为空', trigger: 'change' }],
  menuStatus: [{ required: true, message: '菜单状态不能为空', trigger: 'change' }]
})
const systemMenu = reactive<SystemMenu>({
  menuId: props.menu?.menuId,
  parentId: props.menu?.parentId,
  menuType: props.menu?.menuType,
  menuName: props.menu?.menuName,
  menuPath: props.menu?.menuPath,
  menuCode: props.menu?.menuCode,
  component: props.menu?.component,
  hidden: props.menu?.hidden,
  noCache: props.menu?.noCache,
  affix: props.menu?.affix,
  menuIcon: props.menu?.menuIcon,
  menuStatus: props.menu?.menuStatus,
  sort: props.menu?.sort
})
const loading = ref(false)
const emit = defineEmits(['update:modelValue'])
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => {
    emit('update:modelValue', val)
  }
})
const menuFormRef = ref<FormInstance>()
const createMenu = async () => {
  loading.value = true
  await menuFormRef.value?.validate(async (isValid) => {
    if (isValid) {
      const res = await createSystemMenuApi(systemMenu)
      if (res?.code === 200) {
        ElMessage.success('新增成功')
        if (props.refreshList) {
          props.refreshList()
        }
        dialogVisible.value = false
      }
    }
    loading.value = false
  })
}
const updateMenu = async () => {
  loading.value = true
  await menuFormRef.value?.validate(async (isValid) => {
    if (isValid) {
      const res = await updateSystemMenuApi(systemMenu)
      if (res?.code === 200) {
        ElMessage.success('编辑成功')
        if (props.refreshList) {
          props.refreshList()
        }
        dialogVisible.value = false
      }
    }
    loading.value = false
  })
}

const menuStatusList = ref<SelectOption[]>()
const getDictionaryList = async () => {
  menuStatusList.value = getDictionarySelectOptionList('status')
}
getDictionaryList()
const usableMenuList = ref<SelectTreeOption[]>()
const getUsableMenuList = async () => {
  const res = await getUsableMenuListApi()
  if (res) {
    usableMenuList.value = res.data
  }
}
getUsableMenuList()
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('form')
const buttonIcon = ref()
const setIcon = (icon: string) => {
  systemMenu.menuIcon = icon
  buttonIcon.value = useIcon({ icon: icon })
}
const getIconList = (iconList) => {
  if (iconList.length <= queryData.limit) {
    return iconList
  }
  return iconList.slice((queryData.page - 1) * queryData.limit, queryData.page * queryData.limit)
}
const iconTabs = [epIcons, antIcons, tIcons]
const queryData = reactive({
  page: 1,
  limit: 48
})
const clearPage = () => {
  queryData.page = 1
  queryData.limit = 48
}
</script>
<template>
  <div>
    <Dialog v-model="dialogVisible" :title="props.title">
      <el-form
        ref="menuFormRef"
        :model="systemMenu"
        :rules="rules"
        label-width="100px"
        label-position="right"
        status-icon
        :class="prefixCls"
        style="padding-right: 50px; padding-top: 10px"
      >
        <el-row>
          <el-col>
            <el-form-item label="菜单名称" prop="menuName">
              <el-radio-group v-model="systemMenu.menuType">
                <el-radio-button label="0">目录</el-radio-button>
                <el-radio-button label="1">菜单</el-radio-button>
                <el-radio-button label="2">按钮</el-radio-button>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="menuName">
              <el-input v-model="systemMenu.menuName" placeholder="请输入菜单名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="父级菜单" prop="menuName">
              <el-tree-select
                v-model="systemMenu.parentId"
                :data="usableMenuList"
                check-strictly
                :render-after-expand="false"
                placeholder="请输入父级菜单"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单路径" prop="menuPath">
              <el-input
                v-model="systemMenu.menuPath"
                placeholder="请输入菜单路径"
                :disabled="systemMenu.menuType === '2'"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="组件路径" prop="component">
              <el-input
                v-model="systemMenu.component"
                placeholder="请输入组件路径"
                :disabled="systemMenu.menuType !== '1'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="菜单图标" prop="menuIcon">
              <el-input
                v-model="systemMenu.menuIcon"
                placeholder="请选择菜单图标"
                :disabled="systemMenu.menuType === '2'"
              >
                <template #append>
                  <el-popover
                    placement="bottom"
                    :width="530"
                    trigger="click"
                    @before-enter="clearPage"
                  >
                    <template #reference>
                      <el-button :icon="buttonIcon" />
                    </template>
                    <el-tabs tab-position="left" @tab-click="clearPage">
                      <el-tab-pane
                        v-for="(iconTab, tabIndex) in iconTabs"
                        :label="iconTab.name"
                        :key="tabIndex"
                      >
                        <el-scrollbar height="320px" class="icon_list">
                          <span
                            v-for="(item, index) in getIconList(iconTab.icons)"
                            :key="index"
                            class="span_icon"
                          >
                            <Icon :icon="item" class="icon_select" @click="setIcon(item)" />
                          </span>
                        </el-scrollbar>
                        <el-pagination
                          background
                          small
                          :page-size="queryData.limit"
                          v-model:current-page="queryData.page"
                          layout="prev, pager, next"
                          :total="iconTab.icons.length"
                          style="margin-top: 10px"
                          v-show="iconTab.icons.length > 0"
                          @current-change="getIconList"
                        />
                      </el-tab-pane>
                    </el-tabs>
                  </el-popover>
                </template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单编码" prop="menuCode">
              <el-input
                v-model="systemMenu.menuCode"
                placeholder="请输入菜单编码"
                :disabled="systemMenu.menuType === '0'"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="状态" prop="menuStatus">
              <el-select
                v-model="systemMenu.menuStatus"
                placeholder="请选择菜单状态"
                style="width: 100%"
              >
                <el-option
                  v-for="item in menuStatusList"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="排序" prop="sort">
              <el-input-number
                v-model="systemMenu.sort"
                :min="1"
                placeholder="请输入排序编号"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="是否隐藏" prop="hidden">
              <el-switch v-model="systemMenu.hidden" :disabled="systemMenu.menuType === '2'" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="清除缓存" prop="noCache">
              <el-switch v-model="systemMenu.noCache" :disabled="systemMenu.menuType === '2'" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="固定菜单" prop="affix">
              <el-switch v-model="systemMenu.affix" :disabled="systemMenu.menuType === '2'" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button
          type="primary"
          :loading="loading"
          @click="props.create ? createMenu() : updateMenu()"
          >保存</el-button
        >
        <el-button @click="dialogVisible = false">取消</el-button>
      </template>
    </Dialog>
  </div>
</template>
<style lang="less" scoped>
.icon_list {
  width: 100%;
  //height: 320px;
  display: flex;
  justify-content: space-around;
  flex-wrap: wrap; //一定要换行
  //overflow-y: scroll;
  //overflow-x: hidden;
}
.icon_select {
  display: inline-block;
  width: 50px;
  height: 40px;
  color: #000000;
  font-size: 20px;
  border: 1px solid #e6e6e6;
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
  line-height: 40px;
  margin: 5px;

  &:hover {
    color: blue;
    border-color: blue;
  }
}
</style>
